package utils

/*
格式:
START  xxxx  END
例如:
  $XXXX*
*/

type SEBufPack struct {
	matchStart        []byte
	matchEnd          []byte
	rawBuf            []byte
	maxSize           int
	cacheSize         int
	size              int
	decodeL           int
	decodeStep        int
	decodeEndMatchIdx int

	TagCounter int
}

// maxsize 不能为0， 创建rawBuf的大小
func NewSEBufPack(maxsize int) *SEBufPack {
	if maxsize <= 0 {
		maxsize = 1024
	}
	rval := &SEBufPack{
		matchStart: nil,
		matchEnd:   nil,
		maxSize:    maxsize,
		rawBuf:     make([]byte, maxsize),
	}
	return rval
}

func (this *SEBufPack) GetDecodeL() int {
	return this.decodeL
}

func (this *SEBufPack) SetSEBuf(start []byte, end []byte) {
	this.matchStart = make([]byte, len(start))
	copy(this.matchStart, start)

	this.matchEnd = make([]byte, len(end))
	copy(this.matchEnd, end)
}

func (this *SEBufPack) Reset() {
	this.size = 0
	this.cacheSize = 0
	this.decodeEndMatchIdx = 0
	this.decodeStep = 0
}

func (this *SEBufPack) GetRawBuf() []byte {
	return this.rawBuf[:this.size]
}

func (this *SEBufPack) GetSize() int {
	return this.size
}

/**
 *  l: 请求添加几个
 *  result: 添加成功的个数
 */
func (this *SEBufPack) ForceAppend(buf []byte, l int) int {
	r := 0
	if l <= 0 {
		l = len(buf)
	}
	for {
		if r >= len(buf) {
			return r
		}
		if this.size >= this.maxSize {
			return r
		}
		this.rawBuf[this.size] = buf[r]
		this.size++
		r++
		if r == l {
			return r
		}
	}
}

/*
*
直接写入一个字节, -2 写入失败, 0成功
*/
func (this *SEBufPack) ForceAppendByte(val byte) int {
	if this.size >= this.maxSize {
		this.decodeStep = -1
		return -2
	}
	this.rawBuf[this.size] = val
	this.size++
	return 0
}

func (this *SEBufPack) InputBufEx(buf []byte, onBuf func(buf []byte) bool) {
	for i := 0; i < len(buf); i++ {
		r := this.InputByte(buf[i])
		if r == 1 {
			if onBuf != nil {
				if !onBuf(this.GetRawBuf()) {
					break
				}
			}
		}
	}
}

func (this *SEBufPack) InputByte(val byte) int {
	if this.decodeStep == -1 {
		this.Reset()
	}
	if this.size >= this.maxSize {
		this.decodeStep = -1
		return -2
	}
	this.rawBuf[this.size] = val
	this.size++
	this.decodeL++
	if this.size <= len(this.matchStart) {
		if this.matchStart[this.size-1] != this.rawBuf[this.size-1] {
			this.decodeStep = -1
			return -1
		}
		if this.size >= this.maxSize {
			this.decodeStep = -1
			return -2
		}
		return 0
	}

	if this.rawBuf[this.size-1] == this.matchEnd[this.decodeEndMatchIdx] {
		this.decodeEndMatchIdx++
		if len(this.matchEnd) == this.decodeEndMatchIdx {
			this.decodeStep = -1
			return 1
		}

	} else {
		this.decodeEndMatchIdx = 0
	}

	if this.size >= this.maxSize {
		this.decodeStep = -1
		return -2
	}
	return 0
}

/***
 *    0: 需要更多的数据
 *    1: 解码到一个数据包
 *   -1: 数据错误
 *   -2: 超过最大允许大小
 *
 */
func (this *SEBufPack) InputBuf(buf []byte, l int) int {
	if len(this.matchStart) == 0 || len(this.matchEnd) == 0 {
		panic("没有设定matchstart或者mathEnd")
	}
	this.decodeL = 0
	if l <= 0 {
		l = len(buf)
	}
	for {
		if this.size >= this.maxSize {
			return -2
		}
		if this.decodeL >= l {
			return 0
		}
		this.rawBuf[this.size] = buf[this.decodeL]
		this.size++
		this.decodeL++
		if this.size <= len(this.matchStart) {
			if this.matchStart[this.size-1] != this.rawBuf[this.size-1] {
				return -1
			}
			if this.size >= this.maxSize {
				return -2
			}
			continue
		}

		if this.rawBuf[this.size-1] == this.matchEnd[this.decodeEndMatchIdx] {
			this.decodeEndMatchIdx++
			if len(this.matchEnd) == this.decodeEndMatchIdx {
				return 1
			}
		} else {
			this.decodeEndMatchIdx = 0
		}

		if this.size >= this.maxSize {
			return -2
		}

		if this.decodeL == l { // 需要更多的数据
			return 0
		}
	}

}
